package com.cskaoyan.config;

import com.cskaoyan.bean.baseresultVO.BaseRespVo;
import com.cskaoyan.bean.baseresultVO.LoginUserData;
import com.cskaoyan.bean.domain.Admin;
import com.cskaoyan.bean.domain.AdminExample;
import com.cskaoyan.bean.domain.Log;
import com.cskaoyan.mapper.AdminMapper;
import com.cskaoyan.mapper.CouponMapper;
import com.cskaoyan.service.AdminService;
import com.cskaoyan.service.CouponService;
import com.cskaoyan.service.LogService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.RequestHandledEvent;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author looper
 * @
 **/

@Aspect
@Component
public class LogAspectJ {

    @Autowired
    LogService service;

    @Resource
    AdminMapper mapper;

    //    对这个控制器下的所有方法切面
    @Pointcut("execution(* com.cskaoyan.controller.AuthController.login(..))")
    public void getLoginPoint() {
    }


    @Pointcut("execution(* com.cskaoyan.controller..*(..))")
    public void getAllPoint() {
    }


//    @Pointcut("execution(* com.cskaoyan.controller..*(..))")
//    public void getHibernatePoint() {
//    }


    //@Before("getHibernatePoint()")
    public void before() {


    }


    //切入点:对登入登出操作切入:插入到log表中 Auth表下的所有方法
    //需要得到当前的时间1.addTime->操作时间 2.admin "管理员"√ 3.comment:补充信息备注信息 X  4.deleted 5.id号 √
    // 6.ip地址7.result "" == 或者帐号或密码不正确 8 type1(是操作分类) 9更新时间 10 status 布尔值 11.action操作动作

    @Around("getLoginPoint()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Log log = new Log();
        Signature signature = joinPoint.getSignature();
        String methodName = signature.getName();
        String action = "登录";
        // TODO: 2021/12/1 记录其他操作状态
        Object[] obj = joinPoint.getArgs();
        if (obj[0] instanceof Map) {
            Map mapLogin = (Map) obj[0];
            String admin = (String) mapLogin.get("username");
            log.setType(1);
            log.setAdmin(admin);
            log.setResult("登入成功");
            String ip = ((HttpServletRequest) obj[1]).getRemoteAddr();
            log.setIp(ip);
            log.setAddTime(new Date());
            log.setUpdateTime(new Date());
            log.setStatus(true);
            log.setAction(action);
            Integer code = service.insertLog(log);
            Object proceed = joinPoint.proceed();
            BaseRespVo baseRespVo = (BaseRespVo) proceed;
            if (605 == baseRespVo.getErrno()) {
                log.setResult("账户或密码错误");
                log.setAdmin("帐号:"+admin+"尝试登入系统失败");
                service.updateLoginResultStatus(log);
            }
            return proceed;
        }
        return joinPoint.proceed();
    }


    @Around("getAllPoint()")
    public Object aroundAll(ProceedingJoinPoint joinPoint) throws Throwable {

        Signature signature = joinPoint.getSignature();
        String methodeNameGO = signature.getName();
        if (methodeNameGO.contains("login")){
            return joinPoint.proceed();
        }


        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest servletRequest = requestAttributes.getRequest();
        HttpSession session = servletRequest.getSession();
        //session没拿到
//        String admin = (String) session.getAttribute("username");
//        String admin = (String) session.getServletContext().getAttribute("username");
        Admin adminPOJO = null;
        String admin = null;
        Subject subject = SecurityUtils.getSubject();

        if (subject.isAuthenticated()) {
            adminPOJO = (Admin) subject.getPrincipals().getPrimaryPrincipal();
            admin = adminPOJO.getUsername();
        }

        Log logBase = new Log();
        Signature methodeSigature = joinPoint.getSignature();
        String methodeName = methodeSigature.getName();
        //包名类名
        String pakageNameAndClassName = methodeSigature.getDeclaringTypeName();
        logBase.setUpdateTime(new Date());
        logBase.setAddTime(new Date());
        String ip = servletRequest.getRemoteAddr();
        logBase.setIp(ip);
        //action result comment type status
        if (methodeName.contains("delete") || methodeName.contains("Delete")) {
            logBase.setAction("删除");
            //类的名字
            String className = joinPoint.getTarget().getClass().getSimpleName();

            logBase.setResult( className + "模块:删除成功");
            // TODO: 2021/12/1 能否覆盖登录
            logBase.setAdmin(admin);
            if (pakageNameAndClassName!=null) {
                String[] strings = StringUtils.delimitedListToStringArray(pakageNameAndClassName, ".");
                logBase.setComment(strings[3]+"类");
            }
            //删除是2吗
            if (className.equalsIgnoreCase("OrderController")) {
                logBase.setType(2);
            } else {

                logBase.setType(3);
            }
            logBase.setStatus(true);
            Integer code = service.insertLog(logBase);
        }
        if (methodeName.contains("update") || methodeName.contains("Update")) {
            logBase.setAction("修改");
            //类的名字
            String className = joinPoint.getTarget().getClass().getSimpleName();
            logBase.setResult(  className + "模块:修改成功");
            // TODO: 2021/12/1 能否覆盖登录
            logBase.setAdmin(admin);
            if (pakageNameAndClassName!=null) {
                String[] strings = StringUtils.delimitedListToStringArray(pakageNameAndClassName, ".");
                logBase.setComment(strings[3]+"类");
            }
            if (className.equalsIgnoreCase("OrderController")) {
                logBase.setType(2);
            } else {
                logBase.setType(3);
            }
            logBase.setStatus(true);
            Integer code = service.insertLog(logBase);
        }
        if (methodeName.contains("add") || methodeName.contains("insert") ||
                methodeName.contains("Add") || methodeName.contains("Insert") ||
                methodeName.contains("create") || methodeName.contains("Create")) {
            logBase.setAction("插入");
            //类的名字
            String className = joinPoint.getTarget().getClass().getSimpleName();
            logBase.setResult( className + "模块:插入成功");
            logBase.setAdmin(admin);
            // TODO: 2021/12/1 改细节
            if (pakageNameAndClassName!=null) {
                String[] strings = StringUtils.delimitedListToStringArray(pakageNameAndClassName, ".");
            logBase.setComment(strings[3]+"类");
            }

            if (className.equalsIgnoreCase("OrderController")) {
                logBase.setType(2);
            } else {
                logBase.setType(3);
            }
            logBase.setStatus(true);
            Integer code = service.insertLog(logBase);
        }

        return joinPoint.proceed();
    }
}



